// 二维数组顺时针输出

// 顺时针遍历可以看作是 按层处理：
// 从左到右 遍历当前层的最上面一行
// 从上到下 遍历当前层的最右边一列
// 从右到左 遍历当前层的最下面一行（如果还有未遍历的行）
// 从下到上 遍历当前层的最左边一列（如果还有未遍历的列）
// 缩小一层，重复上述步骤，直到所有元素都被访问

function spiralOrder(matrix) {
  if (!matrix.length || !matrix[0].length) return [];

  const result = [];
  let top = 0,
      bottom = matrix.length - 1,
      left = 0,
      right = matrix[0].length - 1;

  while (top <= bottom && left <= right) {
    // 1. 从左到右
    for (let i = left; i <= right; i++) {
      result.push(matrix[top][i]);
    }
    top++;

    // 2. 从上到下
    for (let i = top; i <= bottom; i++) {
      result.push(matrix[i][right]);
    }
    right--;

    // 3. 从右到左（如果还有行）
    if (top <= bottom) {
      for (let i = right; i >= left; i--) {
        result.push(matrix[bottom][i]);
      }
      bottom--;
    }

    // 4. 从下到上（如果还有列）
    if (left <= right) {
      for (let i = bottom; i >= top; i--) {
        result.push(matrix[i][left]);
      }
      left++;
    }
  }

  return result;
}

// 测试
const matrix = [
  [1,  2,  3,  4],
  [5,  6,  7,  8],
  [9, 10, 11, 12]
];
console.log(spiralOrder(matrix));
// 输出: [1, 2, 3, 4, 8, 12, 11, 10, 9, 5, 6, 7]